#include "RingQueue.hpp"
#include "Task.hpp"

struct ThreadData
{
    RingQueue<Task> *rq;
    string threadname;
};

// 消费者
void *Consume(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);
    RingQueue<Task> *rq = td->rq;
    string name = td->threadname;

    while (1)
    {
        // 消费任务
        Task t;
        //输出型参数
        rq->pop(&t);
        t();
        cout << "consumer:" << name << "  getTask: " << t.GetTask() << " ,getResult: " << t.GetResult() << endl;

        sleep(1);
    }

    return nullptr;
}

// 生产者
void *Productor(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);
    RingQueue<Task> *rq = td->rq;
    string name = td->threadname;

    while (1)
    {
        // 生产任务
        int data1 = rand() % 10 + 1;
        int data2 = rand() % 8;
        char op = oper[rand() % oper.size()];
        Task t(data1, data2, op);
        rq->push(t);
        cout << "productor:" << name << "  getTask: " << t.GetTask() << endl;
        
        sleep(1);
    }

    return nullptr;
}

int main()
{
    srand(time(nullptr));
    RingQueue<Task> *rq = new RingQueue<Task>();
    pthread_t c[2], p[3];

    // 创建线程
    for (int i = 0; i < 2; i++)
    {
        ThreadData *td = new ThreadData();
        td->rq = rq;
        td->threadname = "thread-" + to_string(i);
        pthread_create(c + i, nullptr, Consume, td);
        usleep(10);
    }

    for (int i = 0; i < 3; i++)
    {
        ThreadData *td = new ThreadData();
        td->rq = rq;
        td->threadname = "thread-" + to_string(i);
        pthread_create(p + i, nullptr, Productor, td);
        usleep(10);
    }

    // 等待线程
    for (int i = 0; i < 2; i++)
    {
        pthread_join(c[i], nullptr);
    }

    for (int i = 0; i < 3; i++)
    {
        pthread_join(p[i], nullptr);
    }

    return 0;
}